//////////////////////////////////////////////
//	File:		CDXCamera.h
//	Aurthor:	Sebastian Lewicki
//	Purpose:	Camera class included in the DirectX enigine
/////////////////////////////////////////////

#ifndef _CDXCAMERA_H_
#define _CDXCAMERA_H_

// The include files for Direct3D9
#include <d3d9.h>
#include <d3dx9.h>

#include <queue>

#include "Math.h"

using std::queue;

class CDXCamera
{
private:
	D3DXMATRIX				m_Matrix;			// Main Camera matrix
	D3DXMATRIX				m_Projection;		// Camera projection matrix
	D3DXVECTOR3				m_Up;				// Up Vector;
	D3DXVECTOR3				m_Forward;			// Forward Vector;

	queue<D3DXMATRIX>		m_Buffer;				// Used for the soft attach

public:

	////////////////////////////////////////////////////////////
	//	Function:	CDXCamera
	//	Purpose:	Constructor
	//	In:			Flag to choose between left or right handed coordinates
	////////////////////////////////////////////////////////////
	CDXCamera(bool bRightHanded = true);

	////////////////////////////////////////////////////////////
	//	Function:	CDXCamera
	//	Purpose:	Constructor
	//	In:			A vector of 3 floats for the position
	//	In:			Flag to choose between left or right handed coordinates
	////////////////////////////////////////////////////////////
	CDXCamera(D3DXVECTOR3 fPos, bool bRightHanded = true);

	////////////////////////////////////////////////////////////
	//	Function:	CDXCamera
	//	Purpose:	Constructor
	//	In:			Position on the X-Axis
	//	In:			Position on the Y-Axis
	//	In:			Position on the Z-Axis
	//	In:			Flag to choose between left or right handed coordinates
	////////////////////////////////////////////////////////////
	CDXCamera(float fX, float fY, float fZ, bool bRightHanded = true);

	////////////////////////////////////////////////////////////
	//	Function:	~CDXCamera
	//	Purpose:	Destructor
	////////////////////////////////////////////////////////////
	~CDXCamera();

	////////////////////////////////////////////////////////////
	//	Function:	CreateProjMatrixLH
	//	Purpose:	Creates the projection matrix from the field of view using left handed coordinate system
	//	In:			Float variable for the field of view, in radians.
	//	In:			Aspect ratio, defined as view space width divided by height.
	//	In:			Float variable for the near plane.
	//	In:			Float variable for the far plane.
	//	Out:		Returns a set projection matrix
	////////////////////////////////////////////////////////////
	D3DXMATRIX	CreateProjMatrixLH(float fFoV, float fAspect, float fNear, float fFar);

	////////////////////////////////////////////////////////////
	//	Function:	CreateProjMatrix
	//	Purpose:	Creates the projection matrix from the field of view
	//	In:			Float variable for the field of view, in radians.
	//	In:			Aspect ratio, defined as view space width divided by height.
	//	In:			Float variable for the near plane.
	//	In:			Float variable for the far plane.
	//	Out:		Returns a set projection matrix
	////////////////////////////////////////////////////////////
	D3DXMATRIX	CreateProjMatrix(float fFoV, float fAspect, float fNear, float fFar);

	////////////////////////////////////////////////////////////
	//	Function:	LookAtLH
	//	Purpose:	Modifies the camera matrix to look at a target (left handed)
	//	In:			the target's position
	//	Out:		Returns the new camera matrix
	////////////////////////////////////////////////////////////
	D3DXMATRIX	LookAtLH(D3DXVECTOR3* fTargetPosition);

	////////////////////////////////////////////////////////////
	//	Function:	LookAtLH
	//	Purpose:	Modifies the camera matrix to look at a target (left handed)
	//	In:			the target's position on the X-Axis
	//	In:			the target's position on the Y-Axis
	//	In:			the target's position on the Z-Axis
	//	Out:		Returns the new camera matrix
	////////////////////////////////////////////////////////////
	D3DXMATRIX	LookAtLH(float fTargetXPositionX, float fTargetPositionY, float fTargetPositionZ);

	////////////////////////////////////////////////////////////
	//	Function:	LookAt
	//	Purpose:	Modifies the camera matrix to look at a target
	//	In:			the target's position
	//	Out:		Returns the new camera matrix
	////////////////////////////////////////////////////////////
	D3DXMATRIX	LookAt(D3DXVECTOR3* fTargetPosition);

	////////////////////////////////////////////////////////////
	//	Function:	LookAt
	//	Purpose:	Modifies the camera matrix to look at a target
	//	In:			the target's position on the X-Axis
	//	In:			the target's position on the Y-Axis
	//	In:			the target's position on the Z-Axis
	//	Out:		Returns the new camera matrix
	////////////////////////////////////////////////////////////
	D3DXMATRIX	LookAt(float fTargetXPositionX, float fTargetPositionY, float fTargetPositionZ);

	////////////////////////////////////////////////////////////
	//	Function:	SoftAttachLH
	//	Purpose:	Modifies the camera matrix to follow the target with a time delay (left handed)
	//	In:			Matrix of the target
	//	In:			Vector to offset by
	//	Out:		Returns the new camera matrix
	////////////////////////////////////////////////////////////
	D3DXMATRIX	SoftAttachLH(D3DXMATRIX& Target, D3DXVECTOR3& Offset);

	////////////////////////////////////////////////////////////
	//	Function:	SoftAttach
	//	Purpose:	Modifies the camera matrix to follow the target with a time delay
	//	In:			Matrix of the target
	//	In:			Vector to offset by
	//	Out:		Returns the new camera matrix
	////////////////////////////////////////////////////////////
	D3DXMATRIX	SoftAttach(D3DXMATRIX& Target, D3DXVECTOR3& Offset);

#pragma region Mutators
	////////////////////////////////////////////////////////////
	//	Function:	SetPosition
	//	Purpose:	Sets the cameras position
	//	In:			Position vector
	////////////////////////////////////////////////////////////
	void	SetPosition(D3DXVECTOR3 fPosition);

	////////////////////////////////////////////////////////////
	//	Function:	SetPosition
	//	Purpose:	Sets the cameras position
	//	In:			Position along the X-Axis
	//	In:			Position along the Y-Axis
	//	In:			Position along the Z-Axis
	////////////////////////////////////////////////////////////
	void	SetPosition(float fPosX, float fPosY, float fPosZ);

#pragma endregion

#pragma region Accessors
	////////////////////////////////////////////////////////////
	//	Function:	GetMat
	//	Purpose:	Returns the Camera's matrix
	//	Out:		Camera's matrix
	////////////////////////////////////////////////////////////
	D3DXMATRIX	GetMat()					{ return m_Matrix; }

#pragma endregion

};

#endif